home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / s0ftpj / LuCe.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  9.6 KB  |  357 lines

  1. /*
  2.  * LuCe.c                Modulo Kernel per Linux per tenere
  3.  *                    d'occhio il sistema, ed aggiungere
  4.  *                    sicurezza 'al volo' ad un 'running'
  5.  *                    preesistente. Contiene una semplice
  6.  *                    implementazione dei securelevel BSD
  7.  *                    in attesa dell'arrivo ufficiale con
  8.  *                    le Linux Capabilities [POSIX 1.e] 
  9.  *                    nel kernel 2.4.x di solide ACL.
  10.  *                    Per maggiori informazioni leggete
  11.  *                    il relativo articolo sul numero 8 
  12.  *                    di BFi, liberamente prelevabile e
  13.  *                    consultabile dal seguente URL:
  14.  *
  15.  *                    ---[ http://www.s0ftpj.org/bfi/ ]---
  16.  *
  17.  *                                          __NO__(C)2000 FuSyS [S0ftPj|BFi]
  18.  *                                                        <fusys@s0ftpj.org>
  19.  *
  20.  *
  21.  * Compilate con:               gcc -c -O2 -fomit-frame-pointer LuCe.c
  22.  * Installate con:              insmod LuCe.o <secure=level>
  23.  *
  24.  * 3l33t quote:                 "wow, e funzica anche su Solaris ?"
  25.  * Tnx'n'credits:                         4.4BSD, Daemon9(Hardening the ...), 
  26.  *                    Pragmatic(LKM paper), BFi
  27.  *
  28.  */
  29.  
  30. #define MODULE
  31. #define __KERNEL__
  32. #include <linux/module.h>
  33. #include <linux/fs.h>
  34. #include <linux/ext2_fs.h>
  35. #include <linux/dcache.h>
  36. #include <linux/kdev_t.h>
  37. #include <linux/types.h>
  38. #include <linux/stat.h>
  39. #include <linux/fcntl.h>
  40. #include <linux/mm.h>
  41. #include <sys/syscall.h>
  42. #include <asm/uaccess.h>
  43. #include <asm/unistd.h>
  44. #include <asm/segment.h>
  45.  
  46. #define LKMNAME        "LuCe"
  47. #define DISK        6
  48.  
  49. volatile int secure=0;
  50. MODULE_PARM(secure, "i");
  51.  
  52. char *protetti[10]={"/etc/passwd", "/etc/shadow", "/dev/mem", "/dev/kmem", NULL,
  53.             NULL, NULL, NULL, NULL, NULL};
  54. struct inode luxes[10];
  55.  
  56. extern void *sys_call_table[];
  57. int (*old_open)(const char*, int, mode_t);
  58. int (*old_unlink)(const char*);
  59. int (*old_ioctl) (unsigned int, unsigned int, unsigned long);
  60. int (*old_umount)(char*, int);
  61. int (*old_mount)(char*, char*, char*, unsigned long, void*);
  62. int (*old_execve)(struct pt_regs);
  63. int (*old_query_module)(const char *, int, char *, size_t, size_t *);
  64. unsigned long (*old_create_module)(const char*, size_t);
  65.  
  66. int inocpy(struct inode * inode, struct inode *dest)
  67. {
  68.         if (!dest) return -EFAULT;
  69.         memcpy(dest,inode,sizeof(struct inode));
  70.         return 0;
  71. }
  72.  
  73. int inocmp(struct inode *in1, struct inode *in2)
  74. {
  75.         if (kdev_t_to_nr(in1->i_dev)!=kdev_t_to_nr(in2->i_dev)) return 1;
  76.         if (in1->i_ino!=in2->i_ino) return 1;
  77.         return 0;
  78. }
  79.  
  80. /* ~linux/fs/stat.c */
  81. int do_revalidate(struct dentry *dentry)
  82. {
  83.     struct inode *inode = dentry->d_inode;
  84.     if(inode->i_op && inode->i_op->revalidate)
  85.         return inode->i_op->revalidate(dentry);
  86.     return 0;
  87. }
  88.  
  89. /* ~linux/fs/namei.c */
  90. struct dentry *kernelnamei(const char *name)
  91. {
  92.     struct dentry *dentry;
  93.  
  94.     dentry=lookup_dentry(name, NULL, 1);
  95.     if(!IS_ERR(dentry)){
  96.         if(!dentry->d_inode){
  97.             dput(dentry);
  98.             dentry = ERR_PTR(-ENOENT);
  99.         }
  100.     }
  101.     return dentry;
  102. }
  103.  
  104. /* ~linux/fs/namei.c */
  105. void get_lux_inode(const char *name, struct inode *inode)
  106. {
  107.     struct dentry *dentry;
  108.     int error;
  109.  
  110.     dentry = kernelnamei(name);
  111.     error=PTR_ERR(dentry);
  112.     if(!IS_ERR(dentry)){
  113.         error = do_revalidate(dentry);
  114.         if(!error) inocpy(dentry->d_inode, inode);
  115.         dput(dentry);
  116.     }
  117. }
  118.  
  119. void get_luxes()
  120. {
  121.         int i=0;
  122.  
  123.         while(protetti[i] && i<10) {
  124.                 get_lux_inode(protetti[i], &luxes[i]);
  125.                 i++;
  126.         }
  127. }
  128.  
  129. int lux_open(const char *filename, int flags, int mode)
  130. {
  131.        int i=0;
  132.     struct inode lux;
  133.     char *name;
  134.  
  135.     if(current->pid != 1 || current->p_opptr->pid != 1){
  136.      name=getname(filename);
  137.          get_lux_inode(name, &lux);
  138.  
  139.      while(protetti[i]){
  140.        if(!inocmp(&lux, &luxes[i])){
  141.         if(flags & (O_RDWR|O_WRONLY)){
  142.               printk(KERN_INFO
  143.               "LuCe: Tentativo di Scrittura su %s mediante %s [UID %d TTY %s]\n", 
  144.            filename, current->comm, current->uid,
  145.            current->tty->driver.driver_name);
  146.         putname(name);
  147.                return -EACCES;
  148.            }
  149.            }
  150.              i++;
  151.         }
  152.     
  153.          if(secure) {
  154.             if((S_ISBLK(lux.i_mode))&&(lux.i_gid==DISK)){
  155.                     if(flags & (O_RDWR|O_WRONLY)){
  156.                if(current->pid != 1 || current->p_opptr->pid != 1){
  157.                             printk(KERN_INFO
  158.                             "LuCe: Accesso Raw al disco %s mediante %s [UID %d TTY %s]\n",
  159.                             filename, current->comm, current->uid,
  160.                             current->tty->driver.driver_name);
  161.                             putname(name);
  162.                             return -EACCES;
  163.                }
  164.                        }
  165.                }
  166.          }
  167.     }
  168.        return (*old_open)(filename, flags, mode);
  169. }
  170.  
  171. int lux_unlink(const char *pathname)
  172. {
  173.     int i=0;
  174.     struct inode lux;
  175.     char *name;
  176.     
  177.         name=getname(pathname);
  178.         get_lux_inode(name, &lux);
  179.  
  180.         while(protetti[i]){
  181.                if(!inocmp(&lux, &luxes[i])){
  182.             printk(KERN_INFO
  183.             "LuCe: Tentativo di Unlink su %s mediante %s [UID %d TTY %s]\n",
  184.             pathname, current->comm, current->uid, current->tty->driver.driver_name);
  185.             putname(name);
  186.             return -EACCES;
  187.         }
  188.         i++;
  189.     }
  190.     putname(name);
  191.     return (*old_unlink)(pathname);
  192. }
  193.  
  194. int lux_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
  195. {
  196.     unsigned int flags;
  197.     struct file *f;
  198.     
  199.     if(cmd == EXT2_IOC_SETFLAGS){
  200.        f=current->files->fd[fd];
  201.        if(get_user(flags, (int *)arg)) return -EFAULT;
  202.        if(secure){
  203.         if(((flags&(EXT2_APPEND_FL|EXT2_IMMUTABLE_FL))^
  204.            (f->f_dentry->d_inode->u.ext2_i.i_flags&(EXT2_APPEND_FL|EXT2_IMMUTABLE_FL)))){
  205.             printk(KERN_INFO
  206.             "LuCe: Tentativo di Modifica %s su %s mediante %s [UID %d TTY %s]\n",
  207.             (flags&(EXT2_APPEND_FL))?"EXT2_APPEND_FL":"EXT2_IMMUTABLE_FL",
  208.             f->f_dentry->d_name.name, current->comm, current->uid, 
  209.             current->tty->driver.driver_name); 
  210.             return -EPERM;
  211.         }
  212.         else return (*old_ioctl)(fd, cmd, arg);
  213.        }
  214.     }
  215.     return (*old_ioctl)(fd, cmd, arg);
  216. }
  217.  
  218. int lux_umount(char *name, int flags)
  219. {
  220.     if(secure){
  221.         printk(KERN_INFO
  222.         "LuCe: Tentativo di Umount su %s [UID %d TTY %s]\n", name,
  223.         current->uid, current->tty->driver.driver_name);
  224.         return -EPERM;
  225.     }
  226.     return (*old_umount)(name, flags);
  227. }
  228.  
  229. int lux_mount(char * dev_name, char * dir_name, char * type,
  230.         unsigned long new_flags, void * data)
  231. {
  232.     if(secure){
  233.                 printk(KERN_INFO
  234.                 "LuCe: Tentativo di Mount su %s [UID %d TTY %s]\n", dev_name,
  235.                 current->uid, current->tty->driver.driver_name);
  236.                 return -EPERM;
  237.         }
  238.     return (*old_mount)(dev_name, dir_name, type, new_flags, data);    
  239. }
  240.  
  241. int lux_execve(struct pt_regs regs)
  242. {
  243.     char *filename;
  244.     char **argvs;
  245.     int error;
  246.  
  247.     filename=getname((char *) regs.ebx);
  248.     argvs = (char **)regs.ecx;
  249.     error = PTR_ERR(filename);
  250.         if (IS_ERR(filename)) return error;
  251.     if(strstr(filename, "/sbin/init")){
  252.         if((strstr(argvs[1], "6"))||(strstr(argvs[1], "0"))){
  253.             printk(KERN_INFO "LuCe: Chiusura del Sistema\n");
  254.             secure = 0;
  255.         }
  256.     }
  257.     error = do_execve(filename,(char **)regs.ecx,(char **)regs.edx,®s);
  258.         if (error == 0) current->flags &= ~PF_DTRACE;
  259.     putname(filename);
  260.     return error;
  261. }
  262.  
  263. void ttycredit(char *str)
  264. {
  265.        struct tty_struct *mytty;
  266.  
  267.        if((mytty = current->tty) != NULL) {
  268.            (*(mytty->driver).write)(mytty, 0, str, strlen(str));
  269.        }
  270. }
  271.  
  272. unsigned long lux_create_module(const char *name, size_t size)
  273. {
  274.     if(secure){
  275.         printk(KERN_INFO
  276.         "LuCe: Tentativo di Caricamento Modulo %s [UID %d TTY %s]\n",
  277.         name, current->uid, current->tty->driver.driver_name);
  278.         return -EPERM;
  279.     }
  280.     else return (*old_create_module)(name, size);
  281. }
  282.  
  283. int new_query_module(const char *name, int which, char *buf, size_t bufsize,
  284.         size_t *ret)
  285. {
  286.         int res, cnt, errno=0;
  287.         char *ptr, *match;
  288.  
  289.         res = (*old_query_module)(name, which, buf, bufsize, ret);
  290.  
  291.         if(res == -1)
  292.                 return(-errno);
  293.  
  294.         if(which != QM_MODULES)
  295.                 return(res);
  296.  
  297.         ptr = buf;
  298.  
  299.         for(cnt = 0; cnt < *ret; cnt++) {
  300.                 if(!strcmp(LKMNAME, ptr)) {
  301.                         match = ptr;
  302.                         while(*ptr)
  303.                                 ptr++;
  304.                         ptr++;
  305.                         memcpy(match, ptr, bufsize - (ptr - (char *)buf));
  306.                         (*ret)--;
  307.                         return(res);
  308.                 }
  309.                 while(*ptr)
  310.                         ptr++;
  311.                 ptr++;
  312.         }
  313.  
  314.         return(res);
  315. }
  316.  
  317. int init_module(void)
  318. {
  319.        EXPORT_NO_SYMBOLS;
  320.  
  321.     get_luxes();
  322.        old_open = sys_call_table[SYS_open];
  323.        sys_call_table[SYS_open] = (void *) lux_open;
  324.     old_unlink = sys_call_table[SYS_unlink];
  325.     sys_call_table[SYS_unlink] = (void *) lux_unlink;
  326.     old_ioctl = sys_call_table[SYS_ioctl];
  327.     sys_call_table[SYS_ioctl] = (void *) lux_ioctl;
  328.     old_umount = sys_call_table[SYS_umount];
  329.     sys_call_table[SYS_umount] = (void *) lux_umount;
  330.     old_mount = sys_call_table[SYS_mount];
  331.     sys_call_table[SYS_mount] = (void *) lux_mount;
  332.     old_execve = sys_call_table[SYS_execve];
  333.     sys_call_table[SYS_execve] = (void *) lux_execve;
  334.     old_create_module = sys_call_table[SYS_create_module];
  335.     sys_call_table[SYS_create_module] = (void *) lux_create_module;
  336.         old_query_module = sys_call_table[SYS_query_module];
  337.         sys_call_table[SYS_query_module]=(void *) new_query_module;
  338.  
  339.        ttycredit("\n\033[1;32mLuCe \033[1;34m[Linux 2.2.x LKM] by FuSyS [S0ftPj|BFi]\033[0m\r\n\r\n");
  340.        printk(KERN_INFO "LuCe LKM Attivato\n");
  341.        return 0;
  342. }
  343.  
  344. void cleanup_module(void)
  345. {
  346.        sys_call_table[SYS_open] = old_open;
  347.     sys_call_table[SYS_unlink] = old_unlink;
  348.     sys_call_table[SYS_ioctl] = old_ioctl;
  349.     sys_call_table[SYS_umount] = old_umount;
  350.     sys_call_table[SYS_mount] = old_mount;
  351.     sys_call_table[SYS_execve] = old_execve;
  352.     sys_call_table[SYS_create_module] = old_create_module;
  353.         sys_call_table[SYS_query_module] = old_query_module; 
  354.     ttycredit("\n\033[1;34mLuCe LKM Disattivato\033[0m\r\n\r\n");
  355.     printk(KERN_INFO "LuCe LKM Disattivato\n");
  356. }
  357.